<html><head><meta charset="utf-8"/><title>sort</title></head><body><h1>sort</h1><div class="x-wiki-content x-main-content">
 <h3>
  排序算法
 </h3>
 <p>
  排序也是在程序中经常用到的算法。无论使用冒泡排序还是快速排序，排序的核心是比较两个元素的大小。如果是数字，我们可以直接比较，但如果是字符串或者两个对象呢？直接比较数学上的大小是没有意义的，因此，比较的过程必须通过函数抽象出来。通常规定，对于两个元素
  <code>
   x
  </code>
  和
  <code>
   y
  </code>
  ，如果认为
  <code>
   x &lt; y
  </code>
  ，则返回
  <code>
   -1
  </code>
  ，如果认为
  <code>
   x == y
  </code>
  ，则返回
  <code>
   0
  </code>
  ，如果认为
  <code>
   x &gt; y
  </code>
  ，则返回
  <code>
   1
  </code>
  ，这样，排序算法就不用关心具体的比较过程，而是根据比较结果直接排序。
 </p>
 <p>
  JavaScript的
  <code>
   Array
  </code>
  的
  <code>
   sort()
  </code>
  方法就是用于排序的，但是排序结果可能让你大吃一惊：
 </p>
 <pre><code>// 看上去正常的结果:
['Google', 'Apple', 'Microsoft'].sort(); // ['Apple', 'Google', 'Microsoft'];

// apple排在了最后:
['Google', 'apple', 'Microsoft'].sort(); // ['Google', 'Microsoft", 'apple']

// 无法理解的结果:
[10, 20, 1, 2].sort(); // [1, 10, 2, 20]
</code></pre>
 <p>
  第二个排序把
  <code>
   apple
  </code>
  排在了最后，是因为字符串根据ASCII码进行排序，而小写字母
  <code>
   a
  </code>
  的ASCII码在大写字母之后。
 </p>
 <p>
  第三个排序结果是什么鬼？简单的数字排序都能错？
 </p>
 <p>
  这是因为
  <code>
   Array
  </code>
  的
  <code>
   sort()
  </code>
  方法默认把所有元素先转换为String再排序，结果
  <code>
   '10'
  </code>
  排在了
  <code>
   '2'
  </code>
  的前面，因为字符
  <code>
   '1'
  </code>
  比字符
  <code>
   '2'
  </code>
  的ASCII码小。
 </p>
 <p>
  <img alt="douwo" data-src="/files/attachments/1035534501673632/l" src="https://www.liaoxuefeng.com/files/attachments/1035534501673632/l"/>
 </p>
 <p>
  如果不知道
  <code>
   sort()
  </code>
  方法的默认排序规则，直接对数字排序，绝对栽进坑里！
 </p>
 <p>
  幸运的是，
  <code>
   sort()
  </code>
  方法也是一个高阶函数，它还可以接收一个比较函数来实现自定义的排序。
 </p>
 <p>
  要按数字大小排序，我们可以这么写：
 </p>
 <pre><code class="language-x-javascript">'use strict';

var arr = [10, 20, 1, 2];
----
arr.sort(function (x, y) {
    if (x &lt; y) {
        return -1;
    }
    if (x &gt; y) {
        return 1;
    }
    return 0;
});
console.log(arr); // [1, 2, 10, 20]
</code></pre>
 <p>
  如果要倒序排序，我们可以把大的数放前面：
 </p>
 <pre><code>var arr = [10, 20, 1, 2];
arr.sort(function (x, y) {
    if (x &lt; y) {
        return 1;
    }
    if (x &gt; y) {
        return -1;
    }
    return 0;
}); // [20, 10, 2, 1]
</code></pre>
 <p>
  默认情况下，对字符串排序，是按照ASCII的大小比较的，现在，我们提出排序应该忽略大小写，按照字母序排序。要实现这个算法，不必对现有代码大加改动，只要我们能定义出忽略大小写的比较算法就可以：
 </p>
 <pre><code>var arr = ['Google', 'apple', 'Microsoft'];
arr.sort(function (s1, s2) {
    x1 = s1.toUpperCase();
    x2 = s2.toUpperCase();
    if (x1 &lt; x2) {
        return -1;
    }
    if (x1 &gt; x2) {
        return 1;
    }
    return 0;
}); // ['apple', 'Google', 'Microsoft']
</code></pre>
 <p>
  忽略大小写来比较两个字符串，实际上就是先把字符串都变成大写（或者都变成小写），再比较。
 </p>
 <p>
  从上述例子可以看出，高阶函数的抽象能力是非常强大的，而且，核心代码可以保持得非常简洁。
 </p>
 <p>
  最后友情提示，
  <code>
   sort()
  </code>
  方法会直接对
  <code>
   Array
  </code>
  进行修改，它返回的结果仍是当前
  <code>
   Array
  </code>
  ：
 </p>
 <pre><code>var a1 = ['B', 'A', 'C'];
var a2 = a1.sort();
a1; // ['A', 'B', 'C']
a2; // ['A', 'B', 'C']
a1 === a2; // true, a1和a2是同一对象
</code></pre>
</div>
</body></html>